﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Solidi
{
	public sealed class DependencyBuilder : IDependencyBuilder
	{
		private IEnumerable<IDependency> _dependencies;
		private IList<IDependencyBuilder> _builders;

		public DependencyBuilder()
		{
		}

		public DependencyBuilder(IEnumerable<IDependency> dependencies)
		{
			if (dependencies == null)
			{
				throw new ArgumentNullException("dependencies");
			}

			_dependencies = dependencies;
		}

		public IDependencyBuilder AddBuilder(IEnumerable<IDependency> dependencies)
		{
			IDependencyBuilder builder = new DependencyBuilder(dependencies);

			if (_builders == null)
			{
				_builders = new List<IDependencyBuilder>();
			}

			_builders.Add(builder);

			return builder;
		}

		public IEnumerable<IDependency> Dependencies
		{
			get
			{
				IEnumerable<IDependency> dependencies = _dependencies ?? Enumerable.Empty<IDependency>();

				if (_builders != null)
				{
					dependencies = dependencies.Concat(_builders.SelectMany(b => b.Dependencies));
				}

				return dependencies;
			}
		}

		public void Decorate(Func<IEnumerable<IDependency>, IEnumerable<IDependency>> decorator)
		{
			if (decorator == null)
			{
				throw new ArgumentNullException("decorator");
			}

			_dependencies = decorator(_dependencies);

			if (_builders != null)
			{
				foreach (IDependencyBuilder builder in _builders)
				{
					builder.Decorate(decorator);
				}
			}
		}
	}
}
